package com.bestcem.xm.txtanls.grpc.client;

import com.bestcem.bp.grpc.v1.base.Code;
import com.bestcem.bp.xm.user.grpc.v1.services.UserServiceGrpc;
import com.bestcem.bp.xm.user.grpc.v1.services.*;
import com.bestcem.xm.common.core.constant.GrpcClientNames;
import com.bestcem.xm.common.core.uitls.DateUtil;
import com.bestcem.xm.om.grpc.v1.services.*;
import com.bestcem.xm.txtanls.service.dto.user.IndustryDTO;
import com.bestcem.xm.txtanls.service.dto.user.OrgInfoDTO;
import com.bestcem.xm.txtanls.service.dto.user.UserDTO;
import lombok.extern.slf4j.Slf4j;
import net.devh.boot.grpc.client.inject.GrpcClient;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;

/**
 * 倍市得 user 模块相关rpc接口客户端
 *
 * @author XiaoYunSong <ys.xiao@idiaoyan.com>
 * @version v1.0
 * @date 2021/6/21 16:26
 */
@Slf4j
@Service
public class BaseUserGrpcService {
    @GrpcClient(GrpcClientNames.DS_USER)
    private UserServiceGrpc.UserServiceBlockingStub userServiceBlockingStub;

    @GrpcClient(GrpcClientNames.DS_USER)
    private UserGroupServiceGrpc.UserGroupServiceBlockingStub userGroupServiceBlockingStub;

    @GrpcClient(GrpcClientNames.DS_USER)
    private OrgServiceGrpc.OrgServiceBlockingStub orgServiceBlockingStub;

    @GrpcClient(GrpcClientNames.DS_USER)
    private IndustryServiceGrpc.IndustryServiceBlockingStub industryServiceBlockingStub;

    /**
     * 获取用户信息
     *
     * @param userId 用户id
     * @return User info
     * @author XiaoYunSong <ys.xiao@idiaoyan.cn>
     * @date 2021/7/20 14:53
     */
    public UserDTO getUser(String userId) {
        GetUserByIdRequest.Builder builder = GetUserByIdRequest.newBuilder();
        builder.setId(userId);
        try {
            GetUserByIdResponse response = userServiceBlockingStub.getUserById(builder.build());
            if (Objects.isNull(response) || Code.ERROR.equals(response.getStatus().getCode())) {
                log.error("[Txtanls] USER getUser {} Error; ErrorMsg: {}", userId, response);
                return null;
            }
            return responseToUserDTO(response);
        } catch (Exception e) {
            log.error("[Txtanls] USER getUser {} Error; ErrorMsg: {}", userId, e.getMessage(), e);
            return null;
        }
    }

    /**
     * 获取组织下所有用户信息
     *
     * @param orgId 组织id
     * @return User info
     * @author XiaoYunSong <ys.xiao@idiaoyan.cn>
     * @date 2021/7/20 14:53
     */
    public List<UserDTO> listUserByOrgId(String orgId) {
        ListUsersByFilterRequest.Builder builder = ListUsersByFilterRequest.newBuilder();
        UserCondition.Builder userBuilder = UserCondition.newBuilder();
        userBuilder.setOrgId(orgId);
        builder.setUser(userBuilder.buildPartial());
        try {
            ListUsersByFilterResponse response = userServiceBlockingStub.listUsersByFilter(builder.build());
            if (Objects.isNull(response) || Code.ERROR.equals(response.getStatus().getCode())) {
                log.error("[Txtanls] USER listUserByOrgId {} Error; ErrorMsg: {}", orgId, response);
                return null;
            }
            return responseToUserDTOList(response);
        } catch (Exception e) {
            log.error("[Txtanls] USER listUserByOrgId {} Error; ErrorMsg: {}", orgId, e.getMessage(), e);
            return null;
        }
    }

    /**
     * 获取组织信息
     *
     * @author gy.liu
     * @date 2021/6/21
     */
    public OrgInfoDTO getOrganization(String orgId) {
        GetOrgByIdOrCodeRequest.Builder builder = GetOrgByIdOrCodeRequest.newBuilder();
        builder.setId(orgId);
        try {
            GetOrgByIdOrCodeResponse response = orgServiceBlockingStub.getOrgByIdOrCode(builder.buildPartial());
            if (Objects.isNull(response) || Code.ERROR.equals(response.getStatus().getCode())) {
                log.error("[Txtanls] USER getOrganization {} Error; ErrorMsg: {}", orgId, response);
                return null;
            }
            Organization organization = response.getOrg();
            OrgInfoDTO orgInfoDTO = new OrgInfoDTO();
            if (Objects.nonNull(organization)) {
                orgInfoDTO.setId(organization.getId());
                orgInfoDTO.setIndustryID(organization.getIndustryId());
            }
            return orgInfoDTO;
        } catch (Exception e) {
            log.error("[Txtanls] USER getOrganization {} Error; ErrorMsg: {}", orgId, e.getMessage(), e);
            return null;
        }
    }

    /**
     * 获取行业信息
     *
     * @author gy.liu
     * @date 2021/6/21
     */
    public IndustryDTO getIndustry(String industryId) {
        GetIndustryRequest.Builder builder = GetIndustryRequest.newBuilder();
        builder.setId(industryId);
        try {
            GetIndustryResponse response = industryServiceBlockingStub.getIndustry(builder.buildPartial());
            if (Objects.isNull(response) || Code.ERROR.equals(response.getStatus().getCode())) {
                log.error("[Txtanls] USER getIndustry {} Error; ErrorMsg: {}", industryId, response);
                return null;
            }
            Industry industry = response.getIndustry();
            IndustryDTO industryDTO = new IndustryDTO();
            if (Objects.nonNull(industry)) {
                industryDTO.setId(industry.getId());
                industryDTO.setCode(String.valueOf(industry.getCode()));
                industryDTO.setName(industry.getName());
            }
            return industryDTO;
        } catch (Exception e) {
            log.error("[Txtanls] USER getIndustry {} Error; ErrorMsg: {}", industryId, e.getMessage(), e);
            return null;
        }
    }

    /**
     * 获取对应行业code的某个行业的信息
     *
     * @param code 行业code
     * @return IndustryDTO
     * @author XiaoYunSong <ys.xiao@idiaoyan.cn>
     * @date 2021/7/16 15:20
     */
    public IndustryDTO getIndustryByCode(int code) {
        ListIndustriesRequest.Builder builder = ListIndustriesRequest.newBuilder();
        builder.setCode(String.valueOf(code));
        ListIndustriesResponse response;
        try {
            response = industryServiceBlockingStub.listIndustries(builder.build());
            if (Objects.isNull(response) || Code.ERROR.equals(response.getStatus().getCode())) {
                log.error("[Txtanls] USER getIndustryByCode {} Error; ErrorMsg: {}", code, response);
                return null;
            }
        } catch (Exception e) {
            log.error("[Txtanls] USER getIndustryByCode {} Error; ErrorMsg: {}", code, e.getMessage(), e);
            return null;
        }
        List<Industry> list = response.getIndustriesList();
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        Industry industry = list.get(0);
        IndustryDTO industryDTO = new IndustryDTO();
        if (Objects.nonNull(industry)) {
            industryDTO.setId(industry.getId());
            industryDTO.setCode(String.valueOf(industry.getCode()));
            industryDTO.setName(industry.getName());
        }
        return industryDTO;
    }


    // ========================== private model convert ==========================


    /**
     * UserSearchResponse to List<UserDTO>
     *
     * @param response UserSearchResponse
     * @return List<UserDTO>
     * @author XiaoYunSong <ys.xiao@idiaoyan.cn>
     * @date 2021/8/2 14:40
     */
    private List<UserDTO> responseToUserDTOList(ListUsersByFilterResponse response) {
        List<UserDTO> userDTOList = new ArrayList<>();
        List<User> users = response.getUsersList();
        if (!CollectionUtils.isEmpty(users)) {
            for (User user : users) {
                UserDTO userDTO = infoToUserDTO(user);
                if (Objects.nonNull(userDTO)) {
                    userDTOList.add(userDTO);
                }
            }
        }
        return userDTOList;
    }

    /**
     * UserSearchResponse to List<UserDTO>
     *
     * @param response UserSearchResponse
     * @return List<UserDTO>
     * @author XiaoYunSong <ys.xiao@idiaoyan.cn>
     * @date 2021/8/2 14:40
     */
    private UserDTO responseToUserDTO(GetUserByIdResponse response) {
        User user = response.getUser();
        return infoToUserDTO(user);
    }

    /**
     * User to UserDTO
     *
     * @param user User
     * @return UserDTO
     * @author XiaoYunSong <ys.xiao@idiaoyan.cn>
     * @date 2021/8/2 14:40
     */
    private UserDTO infoToUserDTO(User user) {
        if (Objects.isNull(user)) {
            return null;
        }
        UserDTO userDTO = new UserDTO();
        userDTO.setId(user.getId());
        userDTO.setOrgID(user.getOrgId());
        userDTO.setUserName(user.getUsername());
        userDTO.setPassword(user.getPassword());
        userDTO.setSalt(user.getSalt());
        userDTO.setName(user.getName());
        userDTO.setAvatar(user.getAvatar());
        userDTO.setEmail(user.getEmail());
        userDTO.setMobile(user.getPhone());
        userDTO.setStatus(user.getStatus().getNumber());
        // userDTO.setRoleList(user.getRoleListList());
        userDTO.setContent(user.getContent());
        userDTO.setEdition(user.getEdition().getNumber());
        userDTO.setShowIntroduction(user.getShowGuide());
        userDTO.setWxUnionid(user.getWxInfo().getUnionId());
        userDTO.setWxOpenid(user.getWxInfo().getMiniOpenId());
        userDTO.setWxOffiOpenid(user.getWxInfo().getOffiOpenId());
        userDTO.setWxNickname(user.getWxInfo().getNickname());
        userDTO.setFsOpenId(user.getFsInfo().getOpenId());
        userDTO.setFsUnionId(user.getFsInfo().getUnionId());
        userDTO.setFsName(user.getFsInfo().getName());
        userDTO.setSsoName(user.getSsoName());
        userDTO.setIsAccept(user.getAccept());
        userDTO.setLastLoginTime(DateUtil.getLocalDateTime(user.getLastLoginTime()));
        userDTO.setRegisterIp(user.getRegisterIp());
        userDTO.setIsInnerUser(user.getInner());
        //userDTO.setGuide(user.getGuideList());
        Iterator<String> iterator = user.getGuideRecordsList().iterator();
        List<String> guide = new ArrayList<>();
        while (iterator.hasNext()) {
            guide.add(iterator.next());
        }
        userDTO.setGuide(guide);
        // userDTO.setUserIndex(user.getUserIndex().getNumber());
        return userDTO;
    }
}
